/*
 * 描述： <描述>
 * 修改人： rain
 * 修改时间： 2016年10月1日
 * 项目： webmud
 */
package com.rainhy.webcore.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.hibernate.annotations.GenericGenerator;
import org.joda.time.DateTime;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.domain.AbstractPersistable;
import org.springframework.util.ClassUtils;

/**
 * WebMudEntity<br>
 * Auditable接口.或者@CreatedBy,@CreatedDate,@LastModifiedBy,@LastModifiedDate任选一种实现,这里选择接口
 * 
 * @author rain
 * @version [版本号, 2016年10月1日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@MappedSuperclass
public abstract class AbstractAuditable<Operator> implements Persistable<String> {
    private static final long serialVersionUID = 359891321047903217L;
    
    /** 主键 */
    @Id
    @GeneratedValue(generator = "paymentableGenerator")
    @GenericGenerator(name = "paymentableGenerator", strategy = "uuid")
    @Column(length = 32)
    private String id;
    
    @ManyToOne
    @CreatedBy
    private Operator createdBy;
    
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    private Date createdDate;
    
    @ManyToOne
    @LastModifiedBy
    private Operator lastModifiedBy;
    
    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    private Date lastModifiedDate;
    
    @Override
    public boolean equals(Object obj) {
        if (null == obj) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        if (!getClass().equals(ClassUtils.getUserClass(obj))) {
            return false;
        }
        AbstractPersistable<?> that = (AbstractPersistable<?>) obj;
        return null == this.getId() ? false : this.getId().equals(that.getId());
    }
    
    public Operator getCreatedBy() {
        return createdBy;
    }
    
    public DateTime getCreatedDate() {
        return null == createdDate ? null : new DateTime(createdDate);
    }
    
    @Override
    public String getId() {
        return id;
    }
    
    public Operator getLastModifiedBy() {
        return lastModifiedBy;
    }
    
    public DateTime getLastModifiedDate() {
        return null == lastModifiedDate ? null : new DateTime(lastModifiedDate);
    }
    
    @Override
    public int hashCode() {
        int hashCode = 17;
        hashCode += null == getId() ? 0 : getId().hashCode() * 31;
        return hashCode;
    }
    
    /**
     * Must be {@link Transient} in order to ensure that no JPA provider complains because of a missing setter.
     * 
     * @see DATAJPA-622
     * @see org.springframework.data.domain.Persistable#isNew()
     */
    @Override
    @Transient
    public boolean isNew() {
        return null == getId();
    }
    
    public void setCreatedBy(final Operator createdBy) {
        this.createdBy = createdBy;
    }
    
    public void setCreatedDate(final DateTime createdDate) {
        this.createdDate = null == createdDate ? null : createdDate.toDate();
    }
    
    public void setLastModifiedBy(final Operator lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }
    
    public void setLastModifiedDate(final DateTime lastModifiedDate) {
        this.lastModifiedDate = null == lastModifiedDate ? null : lastModifiedDate.toDate();
    }
    
    @Override
    public String toString() {
        return String.format("Entity of type %s with id: %s", this.getClass().getName(), getId());
    }
    
    /**
     * Sets the id of the entity.
     * 
     * @param id the id to set
     */
    protected void setId(final String id) {
        this.id = id;
    }
}
